﻿using System;

class CRC
    {

    /*
      private void button1_Click(object sender, EventArgs e)
        {
            CRC crc = new CRC();
            byte[] array = new byte[] {0xbb,0xbb,0x43,0x43};
            UInt16 crc16 = 0;
            crc16 = crc.Cal_crc16(array, array.Length);
            tbxRawData.AppendText(crc16.ToString());
        }
         */
    public UInt16 Cal_crc16(byte[] data, int size)
        {

            UInt32 i = 0;
            UInt16 crc = 0;
            for (i = 0; i < size; i++)
            {
                crc = UpdateCRC16(crc, data[i]);
            }
            crc = UpdateCRC16(crc, 0);
            crc = UpdateCRC16(crc, 0);

            return (UInt16)(crc);
        }
        public UInt16 UpdateCRC16(UInt16 crcIn, byte bytee)
        {
            UInt32 crc = crcIn;
            UInt32 ins = (UInt32)bytee | 0x100;

            do
            {
                crc <<= 1;
                ins <<= 1;
                if ((ins & 0x100) == 0x100)
                {
                    ++crc;
                }
                if ((crc & 0x10000) == 0x10000)
                {
                    crc ^= 0x1021;
                }
            }
            while (!((ins & 0x10000) == 0x10000));
            return (UInt16)crc;
        }


    /*
     byte[] data = new byte[] { 0x01, 0x03, 0x00, 0x00, 0x00, 0x0a }; // 示例数据
    ushort crc = ComputeCRC(data);
    发送报文格式
    从站地址+功能码+线圈起始地址高字节+线圈起始地址低字节++线圈数量高字节+线圈数量低字节+字节计数+输出值最高字节+…+输出值最低字节+CRC，其中CRC是对除了CRC本身之外的所有字节进行CRC校验得到的。
         */
    /// <summary>
    /// modbus crc
    /// </summary>
    /// <param name="bytes"></param>
    /// <returns></returns>
    public static ushort ComputeCRC(byte[] bytes)
    {
        ushort crc = 0xffff;
        for (int i = 0; i < bytes.Length; i++)
        {
            crc = (ushort)(crc ^ bytes[i]);
            for (int j = 0; j < 8; j++)
            {
                crc = (crc & 0x0001) != 0 ? (ushort)((crc >> 1) ^ 0xa001) : (ushort)(crc >> 1);
            }
        }
        return crc;
    }
}
